local skynet = require "skynet"

local harbor = {}

--[[
	用 master/slave 模式来实现有一定弹性的集群
	（1）每个 skynet 服务都有一个全网唯一的地址，这个地址是一个 32bit 数字，其高 8bit 标识着它所属 slave 的号码。即 harbor id 。
	在 master/slave 网络中，id 为 0 是保留的。所以最多可以有 255 个 slave 节点
	（2）master/slave模式中节点内和节点间的消息通讯是透明的，skynet 核心会根据目的地址的 harbor id 来决定是直接投递消息，
	还是把消息转发给 harbor 服务。
	（3）注意问题：不要把这个模式用于跨机房的组网。所有 slave 节点都应该在同一局域网内（最好在同一交换机下）。
	不应该把系统设计成可以任意上线或下线 slave 的模式。
	（4）组网限制：slave断开，直接弃用，防止其他服务还持有slave的服务地址，新进程可以以相同的harbor id接入，新旧地址可重复
	（5）harbor 复用问题:写脚本启动skynet进程，将harbor id使用id管理器管理，保证拿到不一样的id
]]

--注册一个全局名字。如果 handle 为空，则注册自己
--skynet.name,skynet.register
function harbor.globalname(name, handle)
	handle = handle or skynet.self()
	skynet.send(".cslave", "lua", "REGISTER", name, handle)
end

--查询全局或本地名字对应的服务地址
function harbor.queryname(name)
	return skynet.call(".cslave", "lua", "QUERYNAME", name)
end

--监控slave是否断开？正常则阻塞，否则直接返回
function harbor.link(id)
	skynet.call(".cslave", "lua", "LINK", id)
end

--未连接，一直阻塞，直到连接成功
function harbor.connect(id)
	skynet.call(".cslave", "lua", "CONNECT", id)
end

--slave上监控与master是否正常？用于异常安全退出
function harbor.linkmaster()
	skynet.call(".cslave", "lua", "LINKMASTER")
end

--[[
	利用这组 api 来解决做一次跨节点远程调用，因为节点断开而无法收到回应的问题。注意：link 和 linkmaster 都有一定的开销，
	所以最好在一个节点中只用少量服务调用它来监控组网状态。由它再来分发到业务层。
]]

return harbor
